//---------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------- PORTAL --------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------

	var idPortalGenerator = 1;

	function Portal(portal, piso){
		
		var _self = this;
		
		this.originalDataPortal = portal; //todo ver si 'portal' queda en el contexto
		
		this.id = "id"+ idPortalGenerator++;
		this.piso = piso;
	    this.clase = portal.class_; //{"intra_floor", "inter_floor"}
	    this.type = portal.type; //{"door", "ustair", "dstair"}
	    this.sourceID = portal.sourceID;
	    this.targetID = portal.targetID;
	    this.bidirectional = portal.bidirectional;
	    this.differential = portal.differential;
	    
		this.sourceSpace = null;
		this.targetSpace = null;
		
		this.contour = [];
		this.contourScaled = []; //contorno extendido para poder usar la camara en 1era persono
		
		this.centroid = {x:0, y:0, z:0};
		this.dangling = true;
		
		
		
		this.isUStair = portal.isUStair !== undefined ? portal.isUStair : false;
		
		this.paredes = [];
		
		this.generarParedes = function(){
//			this.paredes.push([{x: 0,y:0, z: 0},{x: 100, y:0,z: 0},{x: 200,y:0, z: 0}],[{x: 0, y:0,z: 0},{x: 0,y:0, z: 400}])
//			return;
			var alt = 0;
			alt = this.sourceSpace.height;
			if (this.dangling){
				var p1 = copyPoint(_self.contourScaled[0],alt);
				var p2 = copyPoint(_self.contourScaled[1],alt);
				var p3 = copyPoint(_self.contourScaled[2],alt);
				var p4 = copyPoint(_self.contourScaled[3],alt);
			}else{
				var p1 = copyPoint(_self.contour[0],alt);
				var p2 = copyPoint(_self.contour[1],alt);
				var p3 = copyPoint(_self.contour[2],alt);
				var p4 = copyPoint(_self.contour[3],alt);
			}
			
			if (!p1 || !p2){
				console.log('BUGGGGGGGG')
			}
			var mayorDistEnX = true;
			var avanzaHaciaX = true;
			if (Math.abs(p1.x - p2.x) < 3){//el portal avanza hacia Z
				var dX = Math.abs(p1.x - p4.x);
				var dZ = Math.abs(p1.z - p2.z);
				if (dX < dZ){
					this.paredes.push([p1,p4],[p2,p3])
				}else{
					this.paredes.push([p1,p2],[p3,p4])
				}
			}else{//el portal avanza hacia X
				avanzaHaciaX = false;
				var dX = Math.abs(p1.x - p2.x);
				var dZ = Math.abs(p1.z - p4.z);
				if (dX < dZ){
					this.paredes.push([p1,p2],[p3,p4])
				}else{
					this.paredes.push([p1,p4],[p2,p3])
				}
			}
			
			if (mayorDistEnX){
				this.paredes.push([p1,p4],[p2,p3])
			}else{
				
			}
			
		}
		
		
		
		this.getTargetId = function(){
			var componentes = this.targetID.split("\/"); //spliteo el string con el caracter '/'
			
			return {
					edificio: componentes[0],
				//	nivel: this.piso.level,
					piso: componentes[1], 
					space: componentes[2]
				}
		}
		//----------------------------------------------------------
		//--------------------- INIT -------------------------------
		//----------------------------------------------------------
		this.init = function(){
			
			//distingo la clase del portal y de acuerdo a ello defino la forma en que se representaran
			switch (portal.class_){
				case "intra_floor": 

					this.sourceSpace = piso["spaces"][portal.sourceID];
					this.targetSpace = piso["spaces"][portal.targetID]; 
					
					if (!this.sourceSpace || !this.targetSpace) return;
					
					this.sourceSpace.outgoingPortals.push(_self);
					this.targetSpace.outgoingPortals.push(_self);
					
					if (portal.p1 != undefined){
						this.contour.push(copyServerPoint(portal.p1));
						this.contour.push(copyServerPoint(portal.p2));
						
						if (portal.p3 && portal.p4){
							this.contour.push(copyServerPoint(portal.p3));
							this.contour.push(copyServerPoint(portal.p4));
						}else{
							//console.log('ooooooooooooooops');
						}
					}else{
						//console.log('ooooooooooooooops', portal);
					}
					
					generateScaledContour();
					this.dangling = false;
					
					this.generarParedes();
					break;
					
				case "inter_floor": 
				
					this.sourceSpace = piso["spaces"][portal.sourceID];
					
					if (!this.sourceSpace) return;
					
					if (portal.p1 != undefined){
						this.contour.push(copyServerPoint(portal.p1));
						this.contour.push(copyServerPoint(portal.p2));
					}
					
					
					//TODO
					if (portal.p1 != undefined){
						this.contour.push(copyServerPoint(portal.p2));
						this.contour.push(copyServerPoint(portal.p1));
					}

					generateScaledContour();//para generar un dummy
					
					this.sourceSpace.outgoingPortals.push(_self);
					
					break;
			}
		}
		
		
		
		
		
		
		
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		
		
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		//+++++++++++++++++++++++ FUNCIONES ++++++++++++++++++++++++++++++++
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		
		//----------------------------------------------------------
		//------------------- COPY POINT ---------------------
		//----------------------------------------------------------
		//point (como viene del servidor) {x: y:}
		//return {x: z:}
			function copyServerPoint(point){
				var toRet = {x: point.x, z: point.y}
				if (isNaN(toRet.z)){
					console.log('nan')
					
				}
				return toRet;
			}
			
			//point  {x: z:}
			//return {x: z:}
			function copyPoint(point, y){
				if (y !== undefined){
					var toRet = {x: point.x, y: y, z: point.z}
				}else{
					var toRet = {x: point.x, z: point.z}
				}
				
				if (isNaN(toRet.z)){
					console.log('nan')
				}
				return toRet;
			}
		
		
		//----------------------------------------------------------
		//------------------- GENERATE CENTROID ---------------------
		//----------------------------------------------------------
		function generateCentroid(){
			var x = 0;
			var z = 0;
			
			for (var i = 0, l = _self.contour.length; i<l; i++){
				var cont = _self.contour[i];
				x += cont.x;
				z += cont.z;
			}
			x /= _self.contour.length;
			z /= _self.contour.length;
			
			_self.centroid.x = x;
			_self.centroid.z = z;
		};
		
		
		
		//----------------------------------------------------------
		//-------------- GENERATE SCALED CONTOUR -------------------
		//----------------------------------------------------------
		// ACA GENERO EL CONTOUR SCALED (DUMMY) PARA VER SI EL OBJETO SE ENCUENTRA SOBRE EL PORTAL (1st person)
		function generateScaledContour(){
			//if (_self.clase =="inter_floor") console.log('ENTRE generate scaled contour')
			generateCentroid();
			_self.contourScaled = []; //para eliminar el portal dangling
			for (var i = 0, l = _self.contour.length; i < l; i++){
				_self.contourScaled.push(copyPoint(_self.contour[i]));
			}

			var p1 = _self.contourScaled[0];
			var p2 = _self.contourScaled[1];
			var p3 = _self.contourScaled[2];
			var p4 = _self.contourScaled[3];
			
			if (isNaN(p1.x) || isNaN(p2.x) || isNaN(p3.x) ||  isNaN(p4.x)){ //esto no anda (p1.x == p2.x == p3.x == p4.x)
				alert('nan')
			}else if (isNaN(p1.z) || isNaN(p2.z) || isNaN(p3.z) ||  isNaN(p4.z)){
				alert('nan z')
			}
			
			//escalamos los portales para que se solapen con los spaces	
			if (_self.clase == 'inter_floor' || _self.type == "door")
			{
				//TODO chequeo para mezzanines (los portales son 'lineas' y no se genera un poligono (problema interseccion en 1st person)
				var mezzanine = null;
				
				if (p1.x == p2.x && p2.x == p3.x && p3.x == p4.x){ //esto no anda (p1.x == p2.x == p3.x == p4.x)
					mezzanine = "x";
				}else if (p1.z == p2.z && p2.z == p3.z && p3.z == p4.z){
					mezzanine = "z";
				}
				
				var valor = 5;
				if (mezzanine){
					//console.log('mezzanine')
					if (mezzanine == "x"){
						//console.log('generateScaledContour mezanine == X')
						p1.x += valor;
						p2.x += valor;
						p3.x -= valor;
						p4.x -= valor;					
					}else{ //mezzanine == "z"
						//console.log('generateScaledContour mezanine == Z')
						p1.z += valor;
						p2.z += valor;
						p3.z -= valor;
						p4.z -= valor;	
					}
				}else{//no es mezzanine
					
					var valorEscalado = 5;
					
					var mayorDistEnX = true;
					if (p1.x == p2.x){
						var dX = Math.abs(p1.x - p4.x);
						var dZ = Math.abs(p1.z - p2.z);
						if (dX < dZ) mayorDistEnX = false;
					}else{
						var dX = Math.abs(p1.x - p2.x);
						var dZ = Math.abs(p1.z - p4.z);
						if (dX < dZ) mayorDistEnX = false;
					}
					
					for (var i = 0, l = _self.contourScaled.length; i<l; i++){
						var cont = _self.contourScaled[i];
						var attr = "z";
						
						if (!mayorDistEnX) {attr = "x";}
							
						if (cont[attr] - _self.centroid[attr] >= 0){
							cont[attr] += valorEscalado;
						}else{
							cont[attr] -= valorEscalado;
						}
							
						
					}
				}
				
			}else{ //dstair ustair
				
				var dir1 = new THREE.Vector3(p4.x-p1.x, 0/*p3.y-p1.y*/,p4.z-p1.z); //direccion en la que crece la escalera
				
				var aux1 = 8;//alargar
				var aux2 = 0;//afinar
				
				for (var i = 0, l = _self.contourScaled.length; i<l; i++){
					var cont = _self.contourScaled[i];
					var xCentroid = _self.centroid.x;
					var zCentroid = _self.centroid.z;
					
					if (dir1.z == 0 || Math.abs(dir1.z) < 10){//<---  == 0, pide demasiada precision
						if ((cont.x - xCentroid) >= 0){
							cont.x += aux1;
						}else{
							cont.x -= aux1;
						}
					}else{
						if ((cont.x - xCentroid) >= 0){
							cont.x -= aux2;
						}else{
							cont.x += aux2;
						}
					}
					
					if (dir1.x == 0 || Math.abs(dir1.x) < 10){ //<---  == 0, pide demasiada precision
						if ((cont.z - zCentroid) >= 0){
							cont.z += aux1;
						}else{
							cont.z -= aux1;
						}
					}else{
						if ((cont.z - zCentroid) >= 0){
							cont.z -= aux2;
						}else{
							cont.z += aux2;
						}
						
					}
				}
			}
			
			
			//if (_self.clase =="inter_floor") console.log('SALI generate scaled contour')
		};
		
		
		
		
		
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		
		
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		//+++++++++++++++++++++++++++++ API ++++++++++++++++++++++++++++++++
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		
				
		//----------------------------------------------------------
		//---------------------- GET NEXT SPACE --------------------
		//----------------------------------------------------------
		this.getNextSpace = function(space){
			if (USANDO_SPACES_ID){//todo
				switch (space.id){
				case this.sourceSpace.id : //space.id; //06/02/2012
					if (this.targetSpace != null) 
						return this.targetSpace; 
					break;
						
				case this.targetSpace.id : //space.id; //06/02/2012
					if (this.sourceSpace != null)
						return this.sourceSpace; 
			
			};
			}else{
				switch (space.name){
				case this.sourceSpace.name : //space.id; //06/02/2012
					if (this.targetSpace != null) 
						return this.targetSpace; 
					break;
						
				case this.targetSpace.name : //space.id; //06/02/2012
					if (this.sourceSpace != null)
						return this.sourceSpace; 
			
			};
			}
			
			return null; //no esta linkeado o no es bidireccional
		};
		
		
		//----------------------------------------------------------
		//----------------- INTERPOLATE HEIGHT ---------------------
		//----------------------------------------------------------
		//asume que la posicion pasada como parametro se encuentra dentro del contorno del portal
		//todo VER ESCALERAS DIAGONALES
		this.interpolateHeight = function(position, sourceSpace){
			if (this.type != "ustair" && this.type != "dstair"){alert('model_portal error interpolate')};
			
			var pos = new THREE.Vector3();
			pos.copy(position);
			
			var p1 = this.contourScaled[0];
			var p2 = this.contourScaled[1];
			var p3 = this.contourScaled[2];
			var p4 = this.contourScaled[3];
			
			var dir1 = new THREE.Vector3(p4.x-p1.x, 0/*p3.y-p1.y*/,p4.z-p1.z); //direccion en la que crece la escalera
			var largoTotal = dir1.length();
			
			//console.log('type', this.type, 'contour', p1, p2, p3, p4);
			//console.log('dir1', dir1, 'largoTotal', largoTotal);
			
			
			if (dir1.x == 0) pos.x = p4.x;
			if (dir1.z == 0) pos.z = p4.z;
			
			
			var dir2 = new THREE.Vector3(p4.x-pos.x, 0/*p3.y-p1.y*/,p4.z-pos.z); //direccion en la que crece la escalera
			var largo = dir2.length();
			
			var porc = largo/largoTotal;
			
			var heightSpaces = Math.abs(this.sourceSpace.height - this.targetSpace.height);
			
			var mult = (this.type == 'ustair')? 1 : -1;
			
			porc = 1 - porc;//el vector esta armado al reves(patch)
			if (this.sourceSpace == sourceSpace){
							
			}
			//else{mult *= -1}
			//mult *= (this.sourceSpace == sourceSpace)? 1 : -1;
			
			var heightInterpolated = this.sourceSpace.height + mult*heightSpaces*(porc);//+10 altura del cubito
			
			//console.log('dir2', dir2, 'largo', largo);
			//console.log('heightSpaces', heightSpaces, 'heightInterpolated',heightInterpolated);
			
			return heightInterpolated;
		};
		

		
		
		//----------------------------------------------------------
		//----------------- COMPLETE CONTOUR ---------------------
		//----------------------------------------------------------
		this.completeContour = function(_p3, _p4){
			
//			console.info('enrteeeee -> contour', this.contour);
//			console.info(' -> ', this.originalDataPortal.p1, this.originalDataPortal.p2,copyServerPoint(_p3) ,copyServerPoint(_p4));
//			
			
			//restauro puntos originales
			this.contour[0] = copyServerPoint(this.originalDataPortal.p1);
			this.contour[1] = copyServerPoint(this.originalDataPortal.p2);
			
			this.contour[2] = copyServerPoint(_p3);
			this.contour[3] = copyServerPoint(_p4);
			
			
			generateScaledContour();
			this.dangling = false;
			
			
//			console.info('saliiiiiiiiii -> contour,',this.contour,' this.newContour ',  this.newContour )
		}
		
		
		this.contourEsLinea = function(){
			
			var p1 = this.contour[0];
			var p2 = this.contour[1];
			var p3 = this.contour[2];
			var p4 = this.contour[3];
			
			if (p1.x == p2.x && p2.x == p3.x && p3.x == p4.x){ //esto no anda (p1.x == p2.x == p3.x == p4.x)
				return true
			}else if (p1.z == p2.z && p2.z == p3.z && p3.z == p4.z){
				return true
			}else if (p1.x == p4.x && p1.z == p4.z && p2.x == p3.x && p2.z == p3.z){
				return true;
			}
			return false;
				
		}
		
		this.init();
		
};